﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace WcfClientTemplates.Test.Util
{
    public class ResultsHelper
    {
        #region Class Methods (Public)

        /// <summary>
        /// Determines wheter or not the result string is equal to the content of the file
        /// pointed to by testName
        /// </summary>
        /// <param name="testName">The name of the test, corresponding to the .txt file containing the expected test result</param>
        /// <param name="result">The result of the test</param>
        /// <returns>true if the result matches the contenf of the file</returns>
        public static bool AreEqual(string testName, string result)
        {
            bool areEqual = true;
            int lineCount = 0;
            using (MemoryStream stream = new MemoryStream(result.Length))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write(result);
                    writer.Flush();

                    stream.Seek(0, SeekOrigin.Begin);
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        string expectedResultPath = ResultsHelper.GetExpectedResultPath(testName);
                        using (StreamReader expectedReader = new StreamReader(expectedResultPath))
                        {
                            string line = null;
                            string expectedLine = null;
                            while (areEqual && !reader.EndOfStream && !expectedReader.EndOfStream)
                            {
                                lineCount++;
                                line = reader.ReadLine();
                                expectedLine = expectedReader.ReadLine();
                                areEqual = line.TrimEnd(' ', '\t').TrimStart(' ', '\t') == expectedLine.TrimEnd(' ', '\t').TrimStart(' ', '\t');
                            }
                            if (!areEqual)
                                throw new AssertFailedException(string.Format("Generated results differ.\nLine {0}. Expected: \"{1}\". Found: \"{2}\".",
                                    lineCount, expectedLine, line));
                            if (reader.EndOfStream && !expectedReader.EndOfStream)
                                throw new AssertFailedException("Generated file is larger than expected.");
                            if (!reader.EndOfStream && expectedReader.EndOfStream)
                                throw new AssertFailedException("Generated file is shorter than expected.");
                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Loads the content of a test result file
        /// </summary>
        /// <param name="testName">The name of the test, corresponding to the .txt file containing the expected test result</param>
        /// <returns>The content of a test result file</returns>
        public static string LoadExpectedResult(string testName)
        {
            string expected = null;
            string path = ResultsHelper.GetExpectedResultPath(testName);
            expected = File.ReadAllText(path);
            return expected;
        }

        #endregion

        #region Class Methods (Private)

        private static string GetExpectedResultPath(string testName)
        {
            string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase), string.Format("Results\\{0}.txt", testName));
            UriBuilder builder = new UriBuilder(path);
            path = builder.Path;
            return path;
        }

        #endregion
    }
}
